Jx.declare('Jx.platform.browser.event.Dispatcher', {

	$extend: 'Jx.event.Dispatcher',

	$helpers: {

		'Event': 'Jx.platform.browser.lib.Event'

	},

	observableClass: 'Jx.platform.browser.dom.Node',

	objectClass: 'Jx.platform.browser.event.Object',

	defaultView: undefined,

	domAddEventMethod: undefined,

	domRemoveEventMethod: undefined,

	domDispatchEventMethod: undefined,

	engine: undefined,

	dom: undefined,
	
	domEventListeners: undefined,

	listenerClassIndex: {

		'load': 'event.listener.dom.load'

	},

	initializeEvents: function(){

		var o = this.observable,

			engine = this.engine = o.engine,

			methods = engine.eventMethods;

		this.dom = o.node;

		//-- populate dom event methods
		this.domAddEventMethod = methods.addEvent;

		this.domRemoveEventMethod = methods.removeEvent;

		this.domDispatchEventMethod = methods.dispatchEvent;

		this.defaultView = o.defaultView.node;
		
		this.domEventListeners = Jx.instantiate('Jx.lib.Hash');

		this.$super(arguments);

	},

	//-- create event listener here!
	onCreateListener: function(operation){

		operation.config.type = this.$Event.getEventType(operation.name);

		this.$super(arguments);

	},

	onAfterCreateListener: function(operation){

		this.$super(arguments);

		var listener = operation.returnValue,

			type = listener.type();
		
		//-- this is a dom event
		if (type){
			
			this.onAddDomEventListener(type, listener);

			//this.$Event[ this.domAddEventMethod ](
			//
			//	o.node,
			//
			//	listener.type(),
			//
			//	listener.handler()
			//
			//);

		}

	},
	
	onAddDomEventListener: function(type, listener){
		
		var domEvents = this.domEventListeners;
		
		if (!domEvents.isSet(type)){
			
			var collection = [],
			
				callback = function(event){
					
					var o = arguments.callee,
					
						dispatcher = o.dispatcher;
						
					dispatcher.dispatch(
						
						dispatcher.createEvent(o.eventType, {
							
							browser: event || dispatcher.defaultView.event,
							
							target: dispatcher.observable
							
						})
					
					);
					
				};
				
			callback.dispatcher = this;
			
			callback.eventType = type;
			
			collection.domEventCallback = callback;
			
			domEvents.set(type, collection);
			
			//-- listen
			this.$Event[ this.domAddEventMethod ](
			
				this.observable.node,
			
				type,
			
				callback
			
			);
			
		}
		
		domEvents.get().push( listener );
		
	},

	onDestroyListener: function( listener ){

		var o = this.observable,

			type = listener.type();

		if (type && this.domEventListeners.isSet(type)){
			
			this.onRemoveDomEventListener(type, listener);

		}

		this.$super(arguments);

	},
	
	onRemoveDomEventListener: function(type, listener){
		
		var domEvents = this.domEventListeners,
		
			listeners = domEvents.get(type),
			
			index = listeners.indexOf(listener),
			
			callback;
		
		if (index != -1){
			
			listeners.splice(index, 1);
			
		}
		
		if (!listeners.length){
			
			callback = listeners.domEventCallback;
			
			this.$Event[ this.domRemoveEventMethod ](
			
				this.observable.node,
			
				type,
			
				callback
			
			);
			
			delete callback.dispatcher;
			
			delete callback.eventType;
			
			delete listeners.domEventCallback;
			
			domEvents.unset(type);
			
		}
		
	}

	//createEventHandler: function(listener, callback){
	//
	//	var type = this.$Event.getEventType( listener.name() ),
	//
	//		handler;
	//
	//	if (type){
	//
	//		function EventHandlerReceiver( event ){
	//
	//			var o = arguments.callee,
	//
	//				listener = o.listener;
	//
	//			if (!listener.isDestroyed()){
	//
	//				//-- fix event here
	//				event = event || listener.dispatcher.defaultView.event;
	//
	//				o.callback( listener,
	//
	//					listener.dispatcher.createEvent( listener.name(), {
	//
	//						browser: event
	//
	//					})
	//
	//				);
	//
	//			}
	//
	//		}
	//
	//		EventHandlerReceiver.listener = listener;
	//
	//		EventHandlerReceiver.callback = callback;
	//
	//		handler = EventHandlerReceiver;
	//
	//	} else {
	//
	//		handler = this.$super(arguments);
	//		
	//	}
	//
	//	return handler;
	//
	//}

});
